#include <iostream>
#include <vector>
#include <mutex>
#include "Thread.hpp"
#include "LockGuard.hpp"

using namespace ThreadModule;

class ThreadDate
{
public:
    ThreadDate(int& tickets, const std::string& name,pthread_mutex_t& mutex)
        :_tickets(tickets),_name(name),_mutex(&mutex),_total(0)
        {}

    ~ThreadDate()
    {}

    std::string Name()
    {
        return _name;
    }

    int& Tickets()
    {
        return _tickets;
    }

    int& Total()
    {
        return _total;   
    }

    void SubTick()
    {
        _tickets--;
    }

    void Sumtotal()
    {
        _total++;
    }

    pthread_mutex_t* Mutexlock()
    {
        return _mutex;
    }

private:
    int& _tickets;
    std::string _name;
    pthread_mutex_t* _mutex;
    int _total;   
};

// 数据不一致
int g_tickets = 1000; // 共享资源，没有保护的
const int num = 5;



void route(ThreadDate* td)
{
    while(true)
    {
        LockGuard guard(td->Mutexlock()); // 临时对象， RAII风格的加锁和解锁
        //pthread_mutex_lock(&td->Mutexlock());
        if(td->Tickets() > 0)
        {
            usleep(1000);
            std::cout<<td->Name()<<" running, get tickets : " << td->Tickets()<<std::endl;
            td->SubTick();
            //pthread_mutex_unlock(&td->Mutexlock());
            td->Sumtotal();
        }
        else
        {
            //pthread_mutex_unlock(&td->Mutexlock());
            break;
        }
    }
}

int main()
{
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex,nullptr); 

    std::vector<Thread<ThreadDate*>> threads;
    std::vector<ThreadDate*> datas;

    for(int i = 0 ; i < num; i++)
    {
        std::string name = "thread - " + std::to_string(i+1);
        ThreadDate* td = new ThreadDate(g_tickets,name,mutex);
        threads.emplace_back(name,route,td);
        datas.emplace_back(td);
    }

    for(auto& thread:threads)
    {
        thread.Start();
    }

    for(auto& thread:threads)
    {
        thread.Join();
    }

    sleep(1);

    for(auto& data:datas)
    {
        std::cout << data->Name()<<" get tickets: "<< data->Total()<<std::endl;
        delete data;
    }


    return 0;
}
